package com.zyao89.view.zweb;

import com.zyao89.view.zweb.exceptions.ZWebException;
import com.zyao89.view.zweb.inter.IZActivityStateListener;
import com.zyao89.view.zweb.inter.IZWebHandler;
import com.zyao89.view.zweb.inter.IZWebMethodInterface;
import com.zyao89.view.zweb.inter.IZWebOnStateListener;
import com.zyao89.view.zweb.javascript.ZJavaScriptEx;
import com.zyao89.view.zweb.services.ServiceFactory;
import com.zyao89.view.zweb.views.IZWebView;
import ohos.aafwk.ability.AbilityPackage;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.webengine.ResourceResponse;
import ohos.app.Context;

/**
 * @author Zyao89
 * 2017/11/13.
 */
public class ZWebInstance implements IZActivityStateListener, IZWebView.OnPageListener {
    static AbilityPackage sApplication;
    static Context sContext;
    private final ZWebConfig mZWebConfig;
    private final ZWebHandler mZWebHandler;
    private final ServiceFactory mServiceFactory;

    private ZWeb mZWeb;
    private IZWebView mZWebView;
    private ZJavaScriptEx mZJavaScript;
    private IZWebView.OnPageListener mPageListener;

    private ZWebInstance(ZWebConfig config) {
        mZWebConfig = config;
        mZWebHandler = new ZWebHandler(config);
        mServiceFactory = new ServiceFactory(mZWebHandler);
    }

    public static void init(AbilityPackage application) {
        sApplication = application;
    }

    public static void initContext(Context context) {
        sContext = context;
    }

    public static ZWebInstance createInstance(String url) {
        return createInstance(new ZWebConfig.Builder(url).build());
    }

    public static ZWebInstance createInstance(ZWebConfig config) {
        if (sApplication == null) {
            throw new ZWebException("Not Run init...");
        }
        return new ZWebInstance(config);
    }

    public IZWebHandler getZWebHandler() {
        return mZWebHandler;
    }

    public ZWebConfig getZConfig() {
        return mZWebConfig;
    }

    public final void addJavascriptInterface(Object interfaceObj) {
        if (mZWebView == null) {
            throw new ZWebException("First call onActivityCreate(), Please...");
        }
        mZWebView.addJavascriptInterface(interfaceObj, getZConfig().getExposedName());
    }

    public <T> T create(final Class<T> service) {
        return mServiceFactory.create(service);
    }

    @Override
    public void onActivityCreate(ComponentContainer rootView) {
        initWebView(rootView);
        initJavaScript();
        initMainHtml();
    }

    @Override
    public void onActivityStart() {
        if (mZWeb != null) {
            mZWeb.onActivityStart();
        }
    }

    @Override
    public void onActivityPause() {
        if (mZWeb != null) {
            mZWeb.onActivityPause();
        }
    }

    @Override
    public void onActivityResume() {
        if (mZWeb != null) {
            mZWeb.onActivityResume();
        }
    }

    @Override
    public void onActivityStop() {
        if (mZWeb != null) {
            mZWeb.onActivityStop();
        }
    }

    @Override
    public void onActivityDestroy() {
        if (mZWeb != null) {
            mZWeb.onActivityDestroy();
        }
    }

    @Override
    public boolean onActivityBack() {
        if (mZWeb != null) {
            return mZWeb.onActivityBack();
        }
        return false;
    }

    private void initWebView(ComponentContainer rootView) {
        if (mZWeb == null) {
            mZWeb = new ZWeb(this.mZWebHandler);
        }
        mZWeb.setOnPageListener(this);
        mZWebView = mZWeb.getZWebView();
        final Component webView = mZWeb.getView();
        rootView.addComponent(webView, new ComponentContainer.LayoutConfig(
                ComponentContainer.LayoutConfig.MATCH_PARENT,
                ComponentContainer.LayoutConfig.MATCH_PARENT));
    }

    private void initJavaScript() {
        mZJavaScript = new ZJavaScriptEx(mZWebHandler);
        this.setOnStateListener(mZWebConfig.getZWebOnStateListener());
        this.setNativeMethodImplement(mZWebConfig.getZWebMethodInterface());
    }

    private void initMainHtml() {
        mZWebView.addJavascriptInterface(mZJavaScript, getZConfig().getInterName());
        String mainUrl = mZWebConfig.url();
        mZWebView.loadUrl(mainUrl);
    }

    private void setOnStateListener(IZWebOnStateListener interfaceObj) {
        if (mZJavaScript == null) {
            throw new ZWebException("First call onActivityCreate(), Please...");
        }
        mZJavaScript.setOnStateListener(interfaceObj);
    }

    private void setNativeMethodImplement(IZWebMethodInterface interfaceObj) {
        if (mZJavaScript == null) {
            throw new ZWebException("First call onActivityCreate(), Please...");
        }
        mZJavaScript.setNativeMethodImplement(interfaceObj);
    }

    @Override
    public void onReceivedTitle(String title) {

    }

    @Override
    public void onPageStart(String url) {
        mPageListener.onPageStart(url);
    }

    @Override
    public void onPageFinish(String url, boolean canGoBack, boolean canGoForward) {
        mPageListener.onPageFinish(url, canGoBack, canGoForward);
    }

    @Override
    public void onProgressChanged(int newProgress) {

    }

    @Override
    public ResourceResponse shouldInterceptRequest(String url) {
        return null;
    }

    public void setOnPageListener(IZWebView.OnPageListener pageListener) {
        mPageListener = pageListener;
    }
}
